/* Nama File : latar.cpp                            */
/* Deskripsi : Implementasi dari class Latar        */
/* Anggota Kelompok : Dekha Anggareska 13510050		*/
/*                    Fadhil Muhtadin 13510070		*/
/*                    Muhammad Iqbal 13510064		*/
/*                    Yulius Nainggolan 13510090	*/

#include "latar.h"
#include <iostream>
#include <cstdlib>
using namespace std;

	Latar::Latar() : row(3), column(3){
	/* Konstruktor Latar */
    /* I.S. Latar belum tercipta */
    /* F.S. Latar tercipta */
		aCell = new Cell* [getColumn()];
		for (int i=0; i<getColumn(); i++) {
			aCell[i] = new Cell [getRow()];
		}
		//inisialisasi koordinat
		for (int j=0; j<getRow(); j++) {
			for (int i=0; i<getColumn(); i++) {
				aCell[i][j].setX(i);
				aCell[i][j].setY(j);
			}
		}
		// cout << "ctor Latar" << endl;
	};
	
	Latar::Latar(int r, int c) : row(r), column(c) {
	/* Konstruktor Latar dengan parameter */
    /* I.S. Latar belum tercipta */
    /* F.S. Latar tercipta */
		aCell = new Cell* [c];
		for (int i=0; i<c; i++) {
			aCell[i] = new Cell [r];
		}
		//inisialisasi koordinat
		for (int j=0; j<getRow(); j++) {
			for (int i=0; i<getColumn(); i++) {
				aCell[i][j].setX(i);
				aCell[i][j].setY(j);
			}
		}
		// cout << "ctor Latar" << endl;
	};
	
	Latar::~Latar(){
	/* Destruktor Latar */
	/* I.S. Latar terdefinisi */
    /* F.S. Latar dimusnahkan */
		for (int i=0; i<getColumn(); i++) {
			delete [] aCell[i];
		}
		delete [] aCell;
		cout << "dtor latar" << endl;
		// cout << "dtor Latar" << endl;
	};
	
	Latar& Latar::operator=(const Latar& LS) {
	/* operator assignment */
	/* I.S. Latar input terdefinisi */
	/* F.S. Latar output sama dengan Latar input dengan alokasi memori tersendiri */
		for (int i=0; i<getColumn(); i++) {
			delete [] aCell[i];
		}
		delete [] aCell;
		setColumn(LS.getColumn());
		setRow(LS.getRow());
		aCell = new Cell* [LS.getColumn()];
		for (int i=0; i<LS.getColumn(); i++) {
			aCell[i] = new Cell [LS.getRow()];
		}
		//inisialisasi koordinat
		for (int j=0; j<getRow(); j++) {
			for (int i=0; i<getColumn(); i++) {
				aCell[i][j].setX(i);
				aCell[i][j].setY(j);
			}
		}
		B = LS.B;
		// cout << "assignment Latar" << endl;
	};
	
	Latar::Latar(const Latar& LS){
	/* CCtor Latar */
    /* I.S. Latar terdefinisi */
    /* F.S. Latar baru tercipta sebagai kopi Bidang sebelumnya */
		setColumn(LS.getColumn());
		setRow(LS.getRow());
		aCell = new Cell* [LS.getColumn()];
		for (int i=0; i<LS.getColumn(); i++) {
			aCell[i] = new Cell [LS.getRow()];
		}
		//inisialisasi koordinat
		for (int j=0; j<getRow(); j++) {
			for (int i=0; i<getColumn(); i++) {
				aCell[i][j].setX(i);
				aCell[i][j].setY(j);
			}
		}
		B = LS.B;
		// cout << "cctor Latar" << endl;
	};
	
	int Latar::getColumn() const {
	/* Mendapatkan kolom dari Latar */
		return column;
	};
	
	int Latar::getRow() const {
	/* Mendapatkan baris dari Latar */
		return row;
	};
	
	void Latar::setColumn(int ci) {
	/* Melakukan Set terhadap kolom dari Latar */
	/* I.S. Latar terkonstruksi */
    /* F.S. Data kolom bernilai ci */
		column = ci;
	};
	
	void Latar::setRow(int ri) {
	/* Melakukan Set terhadap baris dari Latar */
	/* I.S. Latar terkonstruksi */
    /* F.S. Data baris bernilai ri */
		row = ri;
	};
	
	Bidang* Latar::getBidang(int i) const{
	/* Mengembalikan pointer to Bidang yang disimpan dalam index i */
		return B[i];
	};
	
	void Latar::setBidang(Bidang* BS) {
	/* Menyimpan pointer to Bidang ke dalam List of pointer to Bidang */
	/* I.S. latar terdefinisi dengan List of pointer to Bidang mungkin kosong */
	/* F.S. pointer to Bidang yang disimpan List bertambah satu */
		B.push_back(BS);
	};
	
	Cell Latar::getCell(int m, int n) const {
	/* Mengembalikan Cell yang disimpan dalam matriks yang berindex (m,n) */
		return aCell[m][n];
	}
	
	void Latar::setCell(int m, int n, char ci) {
	/* Mengubah karakter yang disimpan dalam Cell berindeks (m,n) dengan karakter ci */ 
		aCell[m][n].setChar(ci);
	}
	
	void Latar::DrawLatar(){
	/* Menginisialisasi semua cell pada latar dengan Blank */
	/* I.S. Latar terdefinisi */
	/* F.S Tiap cell pada latar berisi karakter blank */
		for (int j=0; j<getRow(); j++){
			for (int i=0; i<getColumn(); i++){
				setCell(i,j,getCell(i,j).getBlank());
				}
			}
	}; 
	
	void Latar::DrawLatarInvers(char ci)
	/* Menginisialisasi semua cell pada latar dengan karakter terdefinisi */
	/* I.S. Latar terdefinisi */
	/* F.S Tiap cell pada latar berisi karakter terdefinisi */
	{
		for (int j=0; j<getRow(); j++){
			for (int i=0; i<getColumn(); i++){
				setCell(i,j,ci);
				}
			}
	}
	
	void Latar::SweepLatar()
	/* Menghapus karakter bidang per baris dan mencetak per frame */
	/* I.S. Semua bidang terisi karakter terdefinisi */
	/* F.S. Semua point pada latar berisi karakter blank dengan pencetakan per frame */
	{
		for (int j=0; j<getRow(); j++) {
			for (int i=0; i<getColumn(); i++) {
				setCell(i,j,getCell(i,j).getBlank());
				system("CLS");
				PrintLatar();
			}
		}
	}
	
	void Latar::PrintLatar() {
	/* Mencetak latar di layar */
	/* I.S. Latar terdefinisi dan tiap cell sudah berisi suatu karakter */
	/* F.S. Tiap cell pada latar tercetak di layar sesuai koordinat pada matriksnya */
		for (int j=getRow()-1; j>=0; j--){
			for (int i=0; i<getColumn(); i++){
				cout << getCell(i,j).getChar() << ' ';
				}
			cout << endl;
			}
	};
	
	void Latar::drawBidang(int k, char ci)
	/* Mengubah semua karakter menjadi karakter yang didefinisikan */
	/* I.S. Latar dan bidang terdefinisi */
	/* F.S. Semua sel dalam bidang berisi karakter yang didefinisikan */
	{
		cout << "size vector: " << B.size() << endl;
		for (int j = 0; j < getRow(); j++) {
			for (int i=0; i < getColumn(); i++) {
				if (getBidang(k)->isPointInside(getCell(i,j))) {
					setCell(i,j,ci);
				}
			}
		}
	};
	
	void Latar::drawAllBidang(char ci)
	/* Mengubah semua karakter dari semua bidang menjadi karakter yang didefinisikan */
	/* I.S. Latar dan bidang terdefinisi */
	/* F.S. Semua sel dalam semua bidang berisi karakter yang didefinisikan */
	{
		for (int z=0; z<B.size(); z++) {
			drawBidang(z, ci);
		}
	}
	
	void Latar::drawBidangInvers(int k)
	/* Mengubah semua karakter diluar bidang menjadi karakter yang didefinisikan */
	/* I.S. Latar dan bidang terdefinisi */
	/* F.S. Semua sel dalam bidang berisi karakter blank sedangkan Cell diluar bidang berisi blank */
	{
		cout << "size vector: " << B.size() << endl;
		for (int j = 0; j < getRow(); j++) {
			for (int i=0; i < getColumn(); i++) {
				if (getBidang(k)->isPointInside(getCell(i,j))) {
					setCell(i,j,getCell(i,j).getBlank());
				}
			}
		}
	}
	
	void Latar::drawAllBidangInvers()
	/* Mengubah semua karakter didalam semua bidang menjadi karakter blank */
	/* I.S. Latar dan bidang terdefinisi */
	/* F.S. Semua sel dalam semua bidang berisi karakter blank */
	{
		for (int z=0; z<B.size(); z++) {
			drawBidangInvers(z);
		}
	}
	
	void Latar::ComputeBN() {
	/* Menampilkan perbandingan karakter dalam bidang dengan karakter 'blank' */
	/* I.S. Latar dan Bidang terdefinisi */
	/* F.S. perbandingan karakter dalam bidang dengan karakter 'blank' tampil di layar */
		int blk = 0;
		int fill = 0;
		for (int j=0; j<getRow(); j++){
			for (int i=0; i<getColumn(); i++){
				if (getCell(i,j).getChar() == '-'){
					blk++;
				}
				else {fill++;}
				}
			}
		cout << "Perbandingan karakter bidang dan karakter blank = " << fill << " : " << blk << endl;
	};
	
	void Latar::ComputeBL() {
	/* Menampilkan perbandingan karakter dalam bidang dengan semua karakter latar */
	/* I.S. Latar dan Bidang terdefinisi */
	/* F.S. perbandingan karakter dalam bidang dengan semua karakter latar tampil di layar */
		int fill = 0;
		for (int j=0; j<getRow(); j++){
			for (int i=0; i<getColumn(); i++){
				if (getCell(i,j).getChar() != '-'){
					fill = fill++;
					}
				}
			}
		cout << "Perbandingan karakter bidang dengan seluruh karakter layar = " << fill << " : " << getRow()*getColumn() << endl;
	};
	
